#!/usr/bin/env node
/**
 * Template/配置一致性检查
 * 当前规则：
 * 1. LOCAL_TEST_COMPONENTS 的 groupCode 必须使用系统白名单（GENERAL/TELECOM/...）
 * 2. LOCAL_TEST 中的组件必须满足 componentType:'AI'、propertiesSource:'1'、stylesSource:'1'
 * 3. 子组件的 groupCode 需与所属分组一致
 */

const fs = require('fs');
const path = require('path');
const ts = require('typescript');

const ALLOWED_GROUP_CODES = new Set(['GENERAL', 'TELECOM', 'CAMPAIGN', 'SHOP', 'CONTAINER', 'TESTCATG']);
const CONSTANTS_FILE = path.join(process.cwd(), 'src/constants/constants.ts');

if (!fs.existsSync(CONSTANTS_FILE)) {
  console.error('❌ 未找到 src/constants/constants.ts');
  process.exit(1);
}

const sourceText = fs.readFileSync(CONSTANTS_FILE, 'utf8');
const sourceFile = ts.createSourceFile(CONSTANTS_FILE, sourceText, ts.ScriptTarget.ESNext, true, ts.ScriptKind.TS);

function getLiteralValue(node) {
  if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
    return node.text;
  }
  if (ts.isNumericLiteral(node)) {
    return node.text;
  }
  return undefined;
}

function findLocalTestArray() {
  let arrayNode = null;
  function visit(node) {
    if (ts.isVariableDeclaration(node)) {
      if (node.name && ts.isIdentifier(node.name) && node.name.text === 'LOCAL_TEST_COMPONENTS') {
        if (node.initializer && ts.isArrayLiteralExpression(node.initializer)) {
          arrayNode = node.initializer;
        }
      }
    }
    ts.forEachChild(node, visit);
  }
  ts.forEachChild(sourceFile, visit);
  return arrayNode;
}

function collectViolations(arrayNode) {
  const issues = [];

  arrayNode.elements.forEach((group, groupIndex) => {
    if (!ts.isObjectLiteralExpression(group)) {
      return;
    }
    let groupCode;
    let groupName;
    let subGroupList;

    group.properties.forEach((prop) => {
      if (!ts.isPropertyAssignment(prop)) return;
      const key = prop.name && prop.name.text;
      if (key === 'groupCode') {
        groupCode = getLiteralValue(prop.initializer);
      }
      if (key === 'groupName') {
        groupName = getLiteralValue(prop.initializer);
      }
      if (key === 'subGroupList' && ts.isArrayLiteralExpression(prop.initializer)) {
        subGroupList = prop.initializer;
      }
    });

    if (!groupCode) {
      issues.push(`[分组${groupIndex}] groupCode 缺失`);
    } else if (!ALLOWED_GROUP_CODES.has(groupCode)) {
      const whitelist = Array.from(ALLOWED_GROUP_CODES).join(', ');
      issues.push(`[分组${groupName || groupIndex}] groupCode='${groupCode}' 不在白名单 ${whitelist}`);
    }

    if (!subGroupList) return;

    subGroupList.elements.forEach((sub, subIndex) => {
      if (!ts.isObjectLiteralExpression(sub)) return;
      let componentList;
      sub.properties.forEach((prop) => {
        if (!ts.isPropertyAssignment(prop)) return;
        if (prop.name && prop.name.text === 'componentList' && ts.isArrayLiteralExpression(prop.initializer)) {
          componentList = prop.initializer;
        }
      });

      if (!componentList) return;

      componentList.elements.forEach((comp, compIndex) => {
        if (!ts.isObjectLiteralExpression(comp)) return;
        const info = {};
        comp.properties.forEach((prop) => {
          if (!ts.isPropertyAssignment(prop)) return;
          const key = prop.name && prop.name.text;
          const value = getLiteralValue(prop.initializer);
          info[key] = value;
        });

        const label = `[分组${groupName || groupIndex}/子分组${subIndex}/组件${info.componentCode || compIndex}]`;
        if (info.componentType !== 'AI') {
          issues.push(`${label} componentType 应为 'AI'，当前为 '${info.componentType}'`);
        }
        if (info.propertiesSource !== '1') {
          issues.push(`${label} propertiesSource 应为 '1'，当前为 '${info.propertiesSource}'`);
        }
        if (info.stylesSource !== '1') {
          issues.push(`${label} stylesSource 应为 '1'，当前为 '${info.stylesSource}'`);
        }
        if (groupCode && info.groupCode && info.groupCode !== groupCode) {
          issues.push(`${label} groupCode='${info.groupCode}' 与分组 '${groupCode}' 不一致`);
        }
      });
    });
  });

  return issues;
}

const localTestArray = findLocalTestArray();
if (!localTestArray) {
  console.error('❌ 未在 constants.ts 中解析到 LOCAL_TEST_COMPONENTS');
  process.exit(1);
}

const problems = collectViolations(localTestArray);
if (problems.length) {
  console.error('❌ 模板一致性检查失败:');
  problems.forEach((issue) => console.error(`  - ${issue}`));
  process.exit(1);
}

console.log('✅ 模板一致性检查通过（LOCAL_TEST_COMPONENTS 配置符合规范）');
